﻿using System;
using Cysharp.Threading.Tasks;
using UnityEngine;
using YooAsset;

namespace UniFramework.Asset
{
	public static class UniAssetSystem
	{
		private static BaseAssetSystem _assetSystem;
		private static AssetConfig _assetConfig;
		private static AssetLoader _globalAssetLoader;

		/// <summary>
		/// 初始化
		/// </summary>
		/// <param name="initFinishCallBack"></param>
		public static async UniTask Init(Action initFinishCallBack = null)
		{
			AssetConfig assetConfig = Resources.Load<AssetConfig>("AssetConfig");
			if (assetConfig == null)
				throw new System.Exception("AssetConfig is null,please create this file to Resources/");
			_assetConfig = assetConfig;
			if (assetConfig.assetLoadMode == EAssetLoadMode.Editor)
			{
				_assetSystem = new DevAssetSystem();
			}
			else if (assetConfig.assetLoadMode == EAssetLoadMode.StreamingAssets)
			{
				_assetSystem = new OfflineAssetSystem();
			}
			else if (assetConfig.assetLoadMode == EAssetLoadMode.AssetBundle)
			{
				_assetSystem = new HostAssetSystem();
			}
			else
			{
				throw new System.Exception("AssetConfig.assetLoadMode is not support");
			}

			await _assetSystem.Init(_assetConfig.defaultPackageName, initFinishCallBack);
			_globalAssetLoader = new AssetLoader();
			_globalAssetLoader.OnInit(_assetSystem._defaultPackage);
		}

		public static void OnDispose()
		{
			_assetSystem?.Dispose();
			_globalAssetLoader?.OnDispose();
		}

		public static AssetLoader GetAssetLoader() => _assetSystem.GetAssetLoader();

		public static T LoadSubAssetsSyncByGlobal<T>(string assetName, string singleAssetName,
			Action<bool, T> loadFinishCallBack)
			where T : UnityEngine.Object =>
			_globalAssetLoader.LoadSubAssetsSync<T>(assetName, singleAssetName, loadFinishCallBack);

		/// <summary>
		/// 同步加载资源
		/// </summary>
		/// <param name="assetName"></param>
		/// <param name="loadFinishCallBack"></param>
		/// <typeparam name="T"></typeparam>
		/// <returns></returns>
		public static T LoadAssetSyncByGlobal<T>(string assetName, Action<bool, T> loadFinishCallBack = null)
			where T : UnityEngine.Object => _globalAssetLoader.LoadAssetSync<T>(assetName, loadFinishCallBack);

		/// <summary>
		/// 注册异步句柄
		/// </summary>
		/// <param name="handle"></param>
		/// <returns></returns>
		public static bool TryRegisterHandleByGlobal(object handle) => _globalAssetLoader.TryRegisterHandle(handle);

		/// <summary>
		/// 取消异步句柄
		/// </summary>
		/// <param name="handle"></param>
		/// <returns></returns>
		public static bool TryUnRegisterHandleByGlobal(object handle) => _globalAssetLoader.TryUnRegisterHandle(handle);


		/// <summary>
		/// 异步加载子资源对象
		/// 异步安全
		/// </summary>
		/// <param name="assetName"></param>
		/// <param name="singleAssetName"></param>
		/// <param name="loadFinishCallBack"></param>
		/// <param name="handler"></param>
		/// <returns></returns>
		public static async UniTask<T> LoadSubAssetsAsyncByGlobal<T>(string assetName, string singleAssetName,
			Action<bool, T> loadFinishCallBack,
			object handler) where T : UnityEngine.Object =>
			await _globalAssetLoader.LoadSubAssetsAsync(assetName, singleAssetName, loadFinishCallBack, handler);

		/// <summary>
		/// 异步加载资源
		/// 异步安全
		/// </summary>
		/// <param name="assetName"></param>
		/// <param name="loadFinishCallBack"></param>
		/// <param name="handler"></param>
		/// <typeparam name="T"></typeparam>
		/// <returns></returns>
		public static async UniTask<T> LoadAssetsAsyncByGlobal<T>(string assetName, Action<bool, T> loadFinishCallBack,
			object handler = null) where T : UnityEngine.Object =>
			await _globalAssetLoader.LoadAssetsAsync(assetName, loadFinishCallBack, handler);

		/// <summary>
		/// 异步加载场景
		/// 异步不安全
		/// </summary>
		/// <param name="sceneName"></param>
		/// <param name="finishCallBack"></param>
		/// <returns></returns>
		/// <exception cref="Exception"></exception>
		public static async UniTask<SceneHandle>
			LoadSceneAsyncByGlobal(string sceneName, Action<bool> finishCallBack = null) =>
			await _globalAssetLoader.LoadSceneAsync(sceneName, finishCallBack);
	}
}